package com.ranyk.www.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ranyk.www.common.enums.MenuTypeEnum;
import com.ranyk.www.entity.Role;
import com.ranyk.www.entity.RoleMenu;
import com.ranyk.www.enums.StatusEnum;
import com.ranyk.www.mapper.RoleMenuMapper;
import com.ranyk.www.mapper.UserRoleMapper;
import com.ranyk.www.pojo.dto.RoleMenuDTO;
import com.ranyk.www.pojo.vo.RoleMenuVO;
import com.ranyk.www.service.IRoleMenuService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * CLASS_NAME: RoleMenuServiceImpl.java <br/>
 *
 * @author ranyk           <br/>
 * @version V1.0           <br/>
 * @decription: 角色目录关联表 业务逻辑层接口实现  <br/>
 * @date: 2022-04-03 <br/>
 */
@Service
public class RoleMenuServiceImpl extends ServiceImpl<RoleMenuMapper, RoleMenu> implements IRoleMenuService {

    private RoleMenuMapper roleMenuMapper;

    private UserRoleMapper userRoleMapper;

	@Autowired
	public void setRoleMenuMapper(RoleMenuMapper roleMenuMapper) {
		this.roleMenuMapper = roleMenuMapper;
	}

	@Autowired
	public void setUserRoleMapper(UserRoleMapper userRoleMapper) {
		this.userRoleMapper = userRoleMapper;
	}

	@Override
    public Set<String> getByRolesId(Set<String> roleIds, Integer status) {
        Set<String> roleMenus = new HashSet<>();

        Set<RoleMenuDTO> menus = roleMenuMapper.listByRoleIds(roleIds, status);

        // 遍历权限列表
        for (RoleMenuDTO menu : menus) {
            if (StringUtils.isNotBlank(menu.getPermission())) {
                // 添加基于Permission的权限信息
                roleMenus.add(menu.getPermission());
            }
        }
        return roleMenus;
    }

    @Override
    public List<RoleMenuVO> listByUserId(Long userId, Integer status) {

        List<RoleMenuVO> menus = new ArrayList<>();

        List<Role> roles = userRoleMapper.listByUserId(userId, status);
        Set<Long> roleIds = new HashSet<>();
        for (Role role : roles) {
            roleIds.add(role.getRoleId());
        }

        // 查询一级目录
        List<RoleMenuDTO> parentAllMenus = roleMenuMapper.listByRoleIdsAndType(roleIds, StatusEnum.SHOW.getStatus(),
                MenuTypeEnum.FIRST_MENU.getType());
        // 去重
        List<RoleMenuDTO> parentMenus = menuReplication(parentAllMenus);
        // 查询二级目录
        List<RoleMenuDTO> childAllMenus = roleMenuMapper.listByRoleIdsAndType(roleIds, StatusEnum.SHOW.getStatus(), MenuTypeEnum.SECOND_MENU.getType());
        // 去重
        List<RoleMenuDTO> childMenus = menuReplication(childAllMenus);

        // 获取根级权限的子级权限
        for (RoleMenuDTO parentMenu : parentMenus) {
            recursionMenu(menus, childMenus, parentMenu);
        }

        return menus;
    }


    @Override
    public List<RoleMenuDTO> listRoleMenus(Integer status) {
        return roleMenuMapper.listRoleMenus(status);
    }

    @Override
    public List<RoleMenuVO> listCheckedMenus(Long roleId, Integer status) {
        // 查询所有目录根据状态
        List<RoleMenuDTO> menus = roleMenuMapper.listRoleMenus(status);

        // 查找该角色拥有的权限
        RoleMenu queryRoleMenu = new RoleMenu();
        queryRoleMenu.setRoleId(roleId);
        List<RoleMenu> roleMenus = roleMenuMapper.selectList(new QueryWrapper<>(queryRoleMenu));

        List<RoleMenuVO> roleMenuVOList = new ArrayList<>();

        // 遍历目录，设置该角色是否选中该目录
        for (RoleMenuDTO menu : menus) {
            RoleMenuVO roleMenuVO = new RoleMenuVO();
            BeanUtils.copyProperties(menu, roleMenuVO);

            for (RoleMenu roleMenu : roleMenus) {
                if (roleMenuVO.getMenuId().equals(roleMenu.getMenuId())) {
                    roleMenuVO.setChecked(true);
                }
            }
			roleMenuVOList.add(roleMenuVO);
        }
        return roleMenuVOList;
    }

    /**
     * 权限去重 （由于数据库中DISTINCT关键词版本报错）
     *
     * @param sourceRoleMenuList 原权限
     * @return 返回去重后的 List 集合,单个实体参见 {@link RoleMenuDTO}
     */
    private List<RoleMenuDTO> menuReplication(List<RoleMenuDTO> sourceRoleMenuList) {
        List<RoleMenuDTO> roleMenuDTOList = new ArrayList<>();
        for (RoleMenuDTO roleMenuDTO : sourceRoleMenuList) {
            if (!roleMenuDTOList.contains(roleMenuDTO)) {
                roleMenuDTOList.add(roleMenuDTO);
            }
        }
        return roleMenuDTOList;
    }

    /**
     * 递归得到每个权限的子级权限
     *
     * @param menus      处理后的目录列表
     * @param childMenus 二级目录列表
     * @param parentMenu 当前一级目录
     */
    private void recursionMenu(List<RoleMenuVO> menus, List<RoleMenuDTO> childMenus, RoleMenuDTO parentMenu) {
        List<RoleMenuDTO> childMenuList = new ArrayList<>();
        for (RoleMenuDTO menu : childMenus) {
            if (parentMenu.getMenuId().equals(menu.getParentId())) {
                childMenuList.add(menu);
            }
        }
        RoleMenuVO parentMenuVo = new RoleMenuVO();
        BeanUtils.copyProperties(parentMenu, parentMenuVo);
        parentMenuVo.setChildMenus(childMenuList);
        menus.add(parentMenuVo);
    }

}
